<?php
/**
 * FP_DataStore class file
 * @package FlickrPhotosetsDB
 */

/**
 * Handles Facebook Data Store operations.
 * 
 * @package FlickrPhotosetsDB
 * @author Brad Dougherty <bdougherty@gmail.com>
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License 3.0
 */
class FP_DataStore extends FP_Database {
	
	/*
	This may be a little difficult to comprehend how this works,
	but here is the gist of it:
	
	For each user we create an object of type 'configuration'.
	We store the FBID of that object in their Preferences at spot 0.
	
	When an action is performed, we create an object of type 'log'.
	We then associate that object with the user's configuration
	object.
	*/
	
	/**
	 * Reference to the facebook object
	 * @var Facebook
	 */
	private $_facebook;
	
	/**
	 * The FBID of the user's preference object.
	 * @var int
	 */
	private $_object_id;
	
	/**
	 * Constructor
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param Facebook $facebook The Facebook object
	 */
	public function __construct($facebook) {
		
		$this->_facebook = $facebook;
		
		// Get the object ID stored in the preferences
		$this->_object_id = $this->get_object_id();
		
		// Check to see that the objects exist, and create them if necessary
		$object_types = $this->_facebook->api_client->data_getObjectTypes();
		if (Utilities::multiArraySearch(self::OBJECT_NAME, $object_types) === false) {
			$this->define_object(self::OBJECT_NAME);
		}
		if (Utilities::multiArraySearch(self::LOG_NAME, $object_types) === false) {
			$this->define_object(self::LOG_NAME);
		}
		
		// Check to see if the associations exist
		$association_definitions = $this->_facebook->api_client->data_getAssociationDefinitions();
		if (Utilities::multiArraySearch(self::LOG_ASSOC, $association_definitions) === false) {
			$this->define_association(self::LOG_ASSOC);
		}
		
	}
	
	/**
	 * Defines the associations required for the app.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param string $name The name of the association to define
	 * @return boolean True if successfully defined
	 */
	private function define_association($name) {
		try {
			
			// Association between log entry and user object
			if ($name == self::LOG_ASSOC) {
				$this->_facebook->api_client->data_defineAssociation(self::LOG_ASSOC, 1,
					array('alias' => 'user_config', 'object_type' => self::OBJECT_NAME),
					array('alias' => 'log_entry', 'object_type' => self::LOG_NAME),
					);
			}
			return true;
			
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/**
	 * Creates the object type and defines its properties.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param string $type The type of object to define
	 * @return boolean True if successfully defined
	 */
	private function define_object($type) {
		try {
			
			// Define the log object
			if ($type == self::LOG_ASSOC) {
				$this->_facebook->api_client->begin_batch();
				& $this->_facebook->api_client->data_createObjectType(self::LOG_ASSOC);
				& $this->_facebook->api_client->data_defineObjectProperty(self::LOG_ASSOC, 'action', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::LOG_ASSOC, 'success', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::LOG_ASSOC, 'extra', PROP_TYPE_BLOB);
				$this->_facebook->api_client->end_batch();
			}
			// Define the configuration object
			else if ($type == self::OBJECT_NAME) {
				$this->_facebook->api_client->begin_batch();
				& $this->_facebook->api_client->data_createObjectType(self::OBJECT_NAME);
				
				// Define the properties
				foreach (self::$properties as $property) {
					& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, $property['name'], $property['type']);
				}
				
				/*
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'facebook_uid', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'facebook_session_key', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'flickr_nsid', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'flickr_token', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'flickr_auth', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_display', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_photo_ids', PROP_TYPE_BLOB);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_count', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_tags', PROP_TYPE_BLOB);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_tagmode', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'profile_sort', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'privacy_filter', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'privacy_visibility', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'privacy_name', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_profile', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_gallery_photostream', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_gallery_photosets', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_gallery_geotagged', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_newsfeed', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_tagging', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'enable_comments', PROP_TYPE_INTEGER);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'last_photo', PROP_TYPE_STRING);
				& $this->_facebook->api_client->data_defineObjectProperty(self::OBJECT_NAME, 'photosets', PROP_TYPE_BLOB);
				*/
				
				$this->_facebook->api_client->end_batch();
			}
			
			return true;
			
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	public function get_info($uid) {
		
		/*
		What we need from this function is the $config array
		*/
		
	}
	
	/**
	 * Retrieves the FBID of the user's preference object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @return int The FBID of the object
	 */
	private function get_object_id() {
		return $this->_facebook->api_client->data_getUserPreference(0);
	}
	
	public function get_recent_tags($minutes = 10) {}
	public function get_uid_from_nsid($nsid) {}
	public function log_install($uid, $success, $extra = '') {}
	public function log_notification($uid, $type, $success, $extra = '') {}
	public function log_remove($uid, $extra = '') {}
	public function log_tag_add($uid, $extra) {}
	public function log_tag_remove($uid, $extra) {}
	public function log_update($uid, $extra = '') {}
	public function remove_flickr_auth($uid) {}
	public function remove_user($uid) {}
	public function save_config($config) {}
	
	/**
	 * Creates the user's object and sets their Facebook ID,
	 * session key, and default values.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $facebook_session_key The Facebook session key
	 * @return boolean True if successfully added
	 */
	public function set_facebook_info($uid, $session_key) {
		try {
			
			// Create the user's object
			$this->_object_id = $this->_facebook->api_client->data_createObject(self::OBJECT_NAME, array(
				'facebook_uid' => $uid,
				'facebook_session_key' => $session_key,
				/*
				default values...
				*/
			));

			// Store the ID as preference 0 and session key as preference 1
			$this->_facebook->api_client->data_setUserPreference(0, $this->_object_id);
			$this->_facebook->api_client->data_setUserPreference(1, $session_key);
			
			// Successful
			return true;
			
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/**
	 * Updates the user's auth level in the data store object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $auth_level The single character string representing the auth level (n, r, w, d)
	 * @return boolean True if successfully updated
	 */
	public function set_flickr_auth($uid, $auth_level) {
		try {
			$this->_facebook->api_client->data_setObjectProperty($this->_object_id, 'flickr_auth', $pid);
			return true;
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/**
	 * Sets the ID of the last photo in the data store object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param int $pid The photo id
	 * @return boolean True if the query was successful
	 */
	public function set_last_photo($uid, $pid) {
		try {
			$this->_facebook->api_client->data_setObjectProperty($this->_object_id, 'last_photo', $pid);
			return true;
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/**
	 * Saves a comma separated list of the user's sets in the data store object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $photosets A comma separated list of the set ids
	 * @return boolean True if the query was successful
	 */
	public function set_photosets($uid, $photosets) {
		try {
			$this->_facebook->api_client->data_setObjectProperty($this->_object_id, 'photosets', $photosets);
			return true;
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/**
	 * Stores the user's Flickr token and NSID in the data store object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param int $nsid The Flickr user id
	 * @param string $token The token returned from Flickr
	 * @return boolean True if successfully added
	 */
	public function store_token($uid, $nsid, $token) {
		try {
			$this->_facebook->api_client->data_UpdateObject($this->_object_id,
				array('flickr_nsid'  => $nsid, 'flickr_token' => $token),
				false);
			return true;
		}
		catch (FacebookRestClientException $e) {
			return false;
		}
	}
	
	/*
	Object and association info
	*/
	const LOG_ASSOC = 'action';
	const LOG_NAME = 'log';
	const OBJECT_NAME = 'configuration';
	
	/*
	Property names, types, and default values
	*/
	public static $properties = array(
		array('name' => 'facebook_uid', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'facebook_session_key', 'type' => PROP_TYPE_STRING, 'default' => ''),
		array('name' => 'flickr_nsid', 'type' => PROP_TYPE_STRING, 'default' => ''),
		array('name' => 'flickr_token', 'type' => PROP_TYPE_STRING, 'default' => ''),
		array('name' => 'flickr_auth', 'type' => PROP_TYPE_STRING, 'default' => ''),
		array('name' => 'profile_display', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'profile_photo_ids', 'type' => PROP_TYPE_BLOB, 'default' => ''),
		array('name' => 'profile_count', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'profile_tags', 'type' => PROP_TYPE_BLOB, 'default' => ''),
		array('name' => 'profile_tagmode', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'profile_sort', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'privacy_filter', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'privacy_visibility', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'privacy_name', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_profile', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_gallery_photostream', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_gallery_photosets', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_gallery_geotagged', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_newsfeed', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'enable_tagging', 'type' => PROP_TYPE_INTEGER, 'default' => 0),
		array('name' => 'enable_comments', 'type' => PROP_TYPE_INTEGER, 'default' => ''),
		array('name' => 'last_photo', 'type' => PROP_TYPE_STRING, 'default' => ''),
		array('name' => 'photosets', 'type' => PROP_TYPE_BLOB, 'default' => ''),
	);
	
	/*
	Object property types
	*/
	const PROP_TYPE_INTEGER = 1;
	const PROP_TYPE_STRING = 2;
	const PROP_TYPE_BLOB = 3;
	
}

?>